package com.gjy.poi.pdf;

import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.borders.Border;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Div;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.UnitValue;

import java.io.IOException;
import java.net.URISyntaxException;

/**
 * 生成《OSB_BP_SOA_HQ_00024 查询服务TOKEN信息服务》规范PDF
 * 运行后：target/TokenServiceSpec.pdf
 */
public class TokenServiceSpecPdf {
    private static final String PREFIX = "D:\\code\\java\\microservice_spc\\utils-all\\poi-all\\src\\main\\resources\\";

    private static final String DEST = PREFIX + "pdf\\TokenServiceSpec.pdf";
    private static final String FONT_FILE = PREFIX + "仿宋_GB2312.ttf";

    public static void main(String[] args) throws IOException, URISyntaxException {
        new TokenServiceSpecPdf().generate();
        System.out.println("PDF 已生成：" + DEST);
    }

    private void generate() throws IOException, URISyntaxException {
        PdfDocument pdf = new PdfDocument(new PdfWriter(DEST));
        pdf.setDefaultPageSize(PageSize.A4);
        Document doc = new Document(pdf);
        PdfFont font = loadFont(FONT_FILE);
        doc.setFont(font).setFontSize(10);

        /* --------- 正文开始 --------- */
        doc.add(title("查询服务TOKEN信息服务规范"));
        doc.add(serviceInfo());
        doc.add(inputSection());
        doc.add(outputSection());
        doc.add(changeLog());
        /* --------- 正文结束 --------- */

        doc.close();
    }

    /* =======================  章节构造  ======================= */

    private Paragraph title(String txt) {
        return new Paragraph(txt)
                .setFontSize(16).setBold()
                .setTextAlignment(TextAlignment.CENTER)
                .setMarginBottom(20);
    }

    /* 1. 服务信息 */
    private Table serviceInfo() {
        Table t = new Table(2).setWidth(UnitValue.createPercentValue(100));
        t.addCell(headCell("服务标识"));
        t.addCell(valCell("OSB_BP_SOA_HQ_00024"));
        t.addCell(headCell("中文名称"));
        t.addCell(valCell("查询服务TOKEN信息服务"));
        t.addCell(headCell("英文名称"));
        t.addCell(valCell("InquiryServiceTokenSrv"));
        t.addCell(headCell("服务版本"));
        t.addCell(valCell("0.1"));
        t.addCell(headCell("服务提供方"));
        t.addCell(valCell("SOA"));
        t.addCell(headCell("同步/异步"));
        t.addCell(valCell("同步"));
        t.addCell(headCell("实现方式"));
        t.addCell(valCell("WebService"));
        t.addCell(headCell("业务场景"));
        t.addCell(valCell("业务系统需在TOKEN失效前调用本服务获取新TOKEN。"));
        t.addCell(headCell("响应时间要求"));
        t.addCell(valCell("<10秒"));
        t.addCell(headCell("峰值并发"));
        t.addCell(valCell("100次/分钟"));
        return t.setMarginBottom(15);
    }

    /* 2. 输入 */
    private Div inputSection() {
        Div div = new Div().setMarginBottom(15);
        div.add(new Paragraph("2. 输入").setBold().setFontSize(12));
        div.add(subTitle("MsgHeader"));
        div.add(tableMsgHeader());
        div.add(subTitle("查询条件"));
        div.add(tableQuery());
        return div;
    }

    /* 3. 输出 */
    private Div outputSection() {
        Div div = new Div().setMarginBottom(15);
        div.add(new Paragraph("3. 输出").setBold().setFontSize(12));
        div.add(tableOutput());
        div.add(subTitle("OUTPUTCOLLECTION（当ESB_FLAG=TRUE时）"));
        div.add(tableOutputCollection());
        return div;
    }

    /* 4. 修改记录 */
    private Table changeLog() {
        Table t = new Table(5).setWidth(UnitValue.createPercentValue(100));
        t.addCell(headCell("日期"));
        t.addCell(headCell("修订者"));
        t.addCell(headCell("版本"));
        t.addCell(headCell("类型"));
        t.addCell(headCell("内容"));
        t.addCell(valCell("2018-03-20"));
        t.addCell(valCell("刘志锋"));
        t.addCell(valCell("V0.1"));
        t.addCell(valCell("A"));
        t.addCell(valCell("创建服务规范文档"));
        return t;
    }

    /* =======================  子表  ======================= */

    private Paragraph subTitle(String txt) {
        return new Paragraph(txt).setBold().setMarginTop(8).setMarginBottom(4);
    }

    private Table tableMsgHeader() {
        Table t = new Table(new float[]{40, 60, 60, 40, 40})
                .setWidth(UnitValue.createPercentValue(100));
        headerRow(t, "序号", "字段名称", "字段描述", "数据类型", "要求");
        row(t, "1", "SOURCESYSTEMID", "服务消费方ID", "VARCHAR2(30)", "Y");
        row(t, "2", "SOURCESYSTEMNAME", "服务消费方名称", "VARCHAR2(30)", "Y");
        row(t, "3", "TOKEN", "令牌认证信息", "VARCHAR2(50)", "Y");
        row(t, "4", "USER_ID", "用户ID", "NUMBER", "N");
        row(t, "5", "USER_NAME", "用户名称", "VARCHAR2(30)", "N");
        return t;
    }

    private Table tableQuery() {
        Table t = new Table(new float[]{40, 60, 60, 40, 40})
                .setWidth(UnitValue.createPercentValue(100));
        headerRow(t, "序号", "字段名称", "字段描述", "数据类型", "要求");
        row(t, "1", "SYSTEM_CODE", "业务系统代码", "VARCHAR2(50)", "Y");
        row(t, "2", "PROVINCE_CODE", "业务系统省份代码", "VARCHAR2(20)", "Y");
        row(t, "3", "CURRENT_TOKEN", "当前TOKEN", "VARCHAR2(100)", "Y");
        return t;
    }

    private Table tableOutput() {
        Table t = new Table(new float[]{40, 60, 60, 40, 40})
                .setWidth(UnitValue.createPercentValue(100));
        headerRow(t, "序号", "字段名称", "字段描述", "数据类型", "备注");
        row(t, "1", "ESB_FLAG", "ESB标识", "VARCHAR2(30)", "TRUE/FALSE");
        row(t, "2", "ESB_RETURN_CODE", "ESB返回代码", "VARCHAR2(50)", "见文档");
        row(t, "3", "ESB_RETURN_MESSAGE", "系统返回消息", "VARCHAR2(2000)", "");
        row(t, "4", "BIZ_SERVICE_FLAG", "业务服务执行标识", "VARCHAR2(30)", "TRUE/FALSE");
        row(t, "5", "BIZ_RETURN_CODE", "业务服务返回代码", "VARCHAR2(30)", "见文档");
        return t;
    }

    private Table tableOutputCollection() {
        Table t = new Table(new float[]{40, 60, 60, 40, 40})
                .setWidth(UnitValue.createPercentValue(100));
        headerRow(t, "序号", "字段名称", "字段描述", "数据类型", "备注");
        row(t, "1", "NEW_TOKEN", "新TOKEN", "VARCHAR2(100)", "");
        row(t, "2", "INVALID_PERIOD", "失效日期", "DATE", "");
        row(t, "3", "OUTPUT_EXT", "查询结果扩展", "VARCHAR2(2000)", "JSON格式");
        return t;
    }

    /* =======================  工具  ======================= */

    private PdfFont loadFont(String s) throws IOException {
        return PdfFontFactory.createFont(s, PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.FORCE_EMBEDDED);
    }

    private void headerRow(Table t, String c1, String c2, String c3, String c4, String c5) {
        t.addHeaderCell(headCell(c1));
        t.addHeaderCell(headCell(c2));
        t.addHeaderCell(headCell(c3));
        t.addHeaderCell(headCell(c4));
        t.addHeaderCell(headCell(c5));
    }

    private void row(Table t, String c1, String c2, String c3, String c4, String c5) {
        t.addCell(valCell(c1));
        t.addCell(valCell(c2));
        t.addCell(valCell(c3));
        t.addCell(valCell(c4));
        t.addCell(valCell(c5));
    }

    private Cell headCell(String txt) {
        return new Cell().add(new Paragraph(txt).setBold().setFontSize(9))
                .setBackgroundColor(ColorConstants.LIGHT_GRAY)
                .setBorder(Border.NO_BORDER).setPadding(4);
    }

    private Cell valCell(String txt) {
        return new Cell().add(new Paragraph(txt).setFontSize(9))
                .setBorder(Border.NO_BORDER).setPadding(3);
    }
}